﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web.DynamicData;
using System.Web.UI;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using NotAClue.Web.DynamicData;
using NotAClue.ComponentModel.DataAnnotations;
using System.Web.UI.WebControls;

namespace NotAClue.Web.DynamicData
{
    /// <summary>
    /// Implements the IAutoFieldGenerator interface and 
    /// supports advanced scenarios such as declarative 
    /// column ordering, workaround for attribute 
    /// localization issues.
    /// </summary>
    public class AdvancedAutoFieldGenerator : IAutoFieldGenerator
    {

        private readonly MetaTable _table;
        private readonly bool _multiItemMode;
        private readonly Boolean _wrapMode;
        private readonly CommandCellPosition _commandCellPosition;
        private readonly Boolean _commandCellWrapMode;
        private readonly Boolean _hideCommandButtons;

        /// <summary>
        /// Allows to explicitly declare which columns should be skipped
        /// </summary>
        public List<MetaColumn> SkipList
        {
            get;
            set;
        }

        /// <summary>
        /// Creates a new Advanced Field Generator.
        /// </summary>
        /// <param name="table">The table this class generates fields for.</param>
        /// <param name="multiItemMode">
        /// <value>true</value> to indicate a 
        /// multi-item control such as GridView, <value>false</value> for 
        /// a single-item control such as DetailsView.
        /// </param>
        public AdvancedAutoFieldGenerator(MetaTable table,
            bool multiItemMode = true,
            CommandCellPosition commandCellPosition = CommandCellPosition.Left,
            Boolean commandCellWrapMode = true,
            Boolean hideCommandButtons = false)
        {
            if (table == null)
                throw new ArgumentNullException("table");

            var tableOptions = table.GetAttributeOrDefault<TableOptionsAttribute>();
            _wrapMode = (Boolean)tableOptions.EnableNoWrap;

            _table = table;
            _multiItemMode = multiItemMode;
            _commandCellPosition = commandCellPosition;
            _commandCellWrapMode = commandCellWrapMode;
            _hideCommandButtons = hideCommandButtons;
        }

        private DynamicField CreateCommandCell()
        {
            // get the first primary key field
            DynamicField cmdCell = new DynamicField();
            cmdCell.HeaderText = "";
            cmdCell.DataField = _table.PrimaryKeyColumns[0].Name;
            cmdCell.UIHint = "GridCommand";
            cmdCell.ItemStyle.Wrap = !_commandCellWrapMode;

            return cmdCell;
        }

        public ICollection GenerateFields(Control control)
        {
            var pageTemplate = PageTemplate.Unknown;
            if (System.Web.HttpContext.Current != null)
            {
                var page = System.Web.HttpContext.Current.Handler as Page;
                if (page != null)
                    pageTemplate = page.GetPageTemplate();
            }

            ContainerType containerType;
            DataBoundControlMode mode;
            switch (pageTemplate)
            {
                case PageTemplate.Unknown:
                case PageTemplate.List:
                case PageTemplate.ListDetails:
                    containerType = ContainerType.List;
                    mode = DataBoundControlMode.ReadOnly;
                    break;
                case PageTemplate.Edit:
                case PageTemplate.EditList:
                    containerType = ContainerType.Item;
                    mode = DataBoundControlMode.Edit;
                    break;
                case PageTemplate.Insert:
                    containerType = ContainerType.Item;
                    mode = DataBoundControlMode.Insert;
                    break;
                case PageTemplate.DetailsList:
                case PageTemplate.Details:
                default:
                    containerType = ContainerType.Item;
                    mode = DataBoundControlMode.ReadOnly;
                    break;
            }

            var fields = new List<DynamicField>();
            var columns = from c in _table.GetScaffoldColumns(mode, containerType)
                          select c;

            //if (!_hideCommandButtons && _commandCellPosition == CommandCellPosition.Left && _table.PrimaryKeyColumns.Count > 0)
            //    fields.Add(CreateCommandCell());

            foreach (var column in columns)
            {
                DynamicField field = new DynamicField()
                {
                    DataField = column.Name,
                    HeaderText = column.DisplayName,
                    //UIHint = column.ConditionalUIHint(_pageTemplate),
                    UIHint = column.UIHint,
                };

                field.ItemStyle.Wrap = !_wrapMode;
                fields.Add(field);
            }

            //if (!_hideCommandButtons && _commandCellPosition == CommandCellPosition.Right && _table.PrimaryKeyColumns.Count > 0)
            //    fields.Add(CreateCommandCell());

            return fields.ToList();
        }

        //protected override DynamicField CreateField(MetaColumn column, ContainerType containerType, DataBoundControlMode mode)
        //{
        //    DynamicField field = base.CreateField(column, containerType, mode);

        //    // override the wrap behavior
        //    // with the noWrap parameter
        //    field.ItemStyle.Wrap = !_noWrap;
        //    return field;
        //}

        //public ICollection GenerateFields(Control control)
        //{
        //    var fields = new List<DynamicField>();
        //    var columns = from c in _table.GetVisibleColumns(_multiItemMode, _pageTemplate)
        //                  select c;
        //    foreach (var column in columns)
        //    {
        //        DynamicField f;
        //        if (column.SecureColumnReadWrite())
        //            f = new DynamicField();
        //        else
        //            f = new DynamicReadonlyField();

        //        f.DataField = column.Name;
        //        f.HeaderText = column.DisplayName;
        //        //f.UIHint = column.ConditionalUIHint(_pageTemplate);
        //        f.UIHint = column.UIHint;
        //        fields.Add(f);
        //    }

        //    return fields.ToList();
        //}
    }
}